package com.example.teaching_server.service;

import com.example.teaching_server.dto.SidebarDTO;
import com.example.teaching_server.entity.TeachingResource;
import com.example.teaching_server.entity.ActivityEntity;
import com.example.teaching_server.entity.NoticeEntity;
import com.example.teaching_server.entity.NoticeTypeEntity;
import com.example.teaching_server.entity.UserEntity;
import com.example.teaching_server.repository.TeachingResourceRepository;
import com.example.teaching_server.repository.ActivityRepository;
import com.example.teaching_server.repository.NoticeRepository;
import com.example.teaching_server.repository.NoticeTypeRepository;
import com.example.teaching_server.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 侧边栏服务
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class SidebarService {

    private final TeachingResourceRepository teachingResourceRepository;
    private final ActivityRepository activityRepository;
    private final NoticeRepository noticeRepository;
    private final NoticeTypeRepository noticeTypeRepository;
    private final UserRepository userRepository;

    /**
     * 获取侧边栏数据
     */
    public SidebarDTO getSidebarData() {
        log.debug("获取侧边栏数据");

        SidebarDTO dto = new SidebarDTO();
        dto.setRecommendations(getRecommendations());
        dto.setNewsNotices(getNewsNotices());
        dto.setCalendar(getCalendarData());
        return dto;
    }

    /**
     * 获取推荐数据
     */
    private SidebarDTO.RecommendationDTO getRecommendations() {
        log.debug("获取推荐数据");

        SidebarDTO.RecommendationDTO recommendationDTO = new SidebarDTO.RecommendationDTO();
        recommendationDTO.setActiveTab("resources");

        try {
            List<TeachingResource> sidebarResources = teachingResourceRepository.findTop4ByOrderByCreatedAtDesc();
            List<TeachingResource> latestResources = sidebarResources.stream()
                    .skip(2)
                    .limit(2)
                    .collect(Collectors.toList());

            recommendationDTO.setResourceRecommendations(
                    latestResources.stream()
                            .map(this::convertToResourceRecommendation)
                            .collect(Collectors.toList())
            );
        } catch (Exception e) {
            log.warn("获取推荐资源失败: {}", e.getMessage());
            recommendationDTO.setResourceRecommendations(new ArrayList<>());
        }

        try {
            List<ActivityEntity> latestActivities = activityRepository.findTop2ByOrderByStartDateDesc();
            recommendationDTO.setActivityRecommendations(
                    latestActivities.stream()
                            .map(this::convertToActivityRecommendation)
                            .collect(Collectors.toList())
            );
        } catch (Exception e) {
            log.warn("获取推荐活动失败: {}", e.getMessage());
            recommendationDTO.setActivityRecommendations(new ArrayList<>());
        }

        return recommendationDTO;
    }

    /**
     * 获取新闻通知数据
     */
    private SidebarDTO.NewsNoticeDTO getNewsNotices() {
        log.debug("获取新闻通知数据");

        SidebarDTO.NewsNoticeDTO newsNoticeDTO = new SidebarDTO.NewsNoticeDTO();
        newsNoticeDTO.setActiveTab("notices");
        newsNoticeDTO.setNewsItems(new ArrayList<>());
        newsNoticeDTO.setNotices(getRealNotices());
        return newsNoticeDTO;
    }

    /**
     * 获取真实通知数据
     */
    private List<SidebarDTO.NoticeItem> getRealNotices() {
        try {
            List<NoticeEntity> latestNotices = noticeRepository.findTopNByOrderByCreatedAtDesc(2);
            return latestNotices.stream()
                    .map(this::convertNoticeToFullDTO)
                    .collect(Collectors.toList());
        } catch (Exception e) {
            log.warn("获取通知数据失败: {}", e.getMessage());
            return new ArrayList<>();
        }
    }

    /**
     * 获取日历数据
     */
    private SidebarDTO.CalendarDTO getCalendarData() {
        SidebarDTO.CalendarDTO calendarDTO = new SidebarDTO.CalendarDTO();
        calendarDTO.setSelectedMonth(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM")));
        calendarDTO.setCalendarDays(new ArrayList<>());
        return calendarDTO;
    }

    /**
     * 将 TeachingResource 转换为 ResourceRecommendation
     */
    private SidebarDTO.ResourceRecommendation convertToResourceRecommendation(TeachingResource resource) {
        SidebarDTO.ResourceRecommendation item = new SidebarDTO.ResourceRecommendation();
        item.setTitle(resource.getTitle());
        item.setDescription(resource.getDescription() != null ?
                resource.getDescription() : "优质教学资源");
        item.setIcon(getResourceIcon(resource.getFileUrl()));
        item.setType(getResourceType(resource.getFileUrl()));
        item.setUrl("/teaching-resources/detail/" + resource.getId());
        return item;
    }

    /**
     * 将 ActivityEntity 转换为 ActivityRecommendation
     */
    private SidebarDTO.ActivityRecommendation convertToActivityRecommendation(ActivityEntity activity) {
        SidebarDTO.ActivityRecommendation item = new SidebarDTO.ActivityRecommendation();
        item.setTitle(activity.getTitle());
        item.setTime(getActivityTime(activity.getStartDate()));
        item.setIcon(getActivityIcon(activity.getBaseName()));
        item.setUrl("/activities/detail/" + activity.getId());
        return item;
    }

    /**
     * 将通知实体转换为完整的通知DTO
     */
    private SidebarDTO.NoticeItem convertNoticeToFullDTO(NoticeEntity notice) {
        SidebarDTO.NoticeItem item = new SidebarDTO.NoticeItem();
        item.setNoticeId(notice.getNoticeId());
        item.setTitle(notice.getTitle());
        item.setContent(notice.getContent());
        item.setDescription(notice.getDescription());
        item.setTime(formatDateTime(notice.getCreatedAt()));
        item.setTypeName(getNoticeTypeName(Math.toIntExact(notice.getTypeId())));
        item.setSenderName(getSenderName(notice.getCreatedBy()));
        item.setCreateTime(formatDateTime(notice.getCreatedAt()));
        item.setUrl("/notices/detail/" + notice.getNoticeId());
        return item;
    }

    /**
     * 获取活动时间
     */
    private String getActivityTime(LocalDate startDate) {
        if (startDate != null) {
            return startDate.format(DateTimeFormatter.ofPattern("MM月dd日"));
        }
        return "时间待定";
    }

    /**
     * 根据文件URL获取资源图标
     */
    private String getResourceIcon(String fileUrl) {
        if (fileUrl == null) return "Document";

        String lowerUrl = fileUrl.toLowerCase();
        if (lowerUrl.contains(".pdf")) return "Document";
        if (lowerUrl.contains(".doc") || lowerUrl.contains(".docx")) return "Document";
        if (lowerUrl.contains(".ppt") || lowerUrl.contains(".pptx")) return "DataBoard";
        if (lowerUrl.contains(".xls") || lowerUrl.contains(".xlsx")) return "DataAnalysis";
        if (lowerUrl.contains(".mp4") || lowerUrl.contains(".avi") || lowerUrl.contains(".mov")) return "VideoPlay";
        if (lowerUrl.contains(".jpg") || lowerUrl.contains(".png") || lowerUrl.contains(".gif")) return "Picture";
        return "Document";
    }

    /**
     * 根据文件URL获取资源类型
     */
    private String getResourceType(String fileUrl) {
        if (fileUrl == null) return "doc";

        String lowerUrl = fileUrl.toLowerCase();
        if (lowerUrl.contains(".pdf")) return "pdf";
        if (lowerUrl.contains(".doc")) return "doc";
        if (lowerUrl.contains(".docx")) return "docx";
        if (lowerUrl.contains(".ppt")) return "ppt";
        if (lowerUrl.contains(".pptx")) return "pptx";
        if (lowerUrl.contains(".xls")) return "xls";
        if (lowerUrl.contains(".xlsx")) return "xlsx";
        if (lowerUrl.contains(".mp4") || lowerUrl.contains(".avi") || lowerUrl.contains(".mov")) return "video";
        if (lowerUrl.contains(".jpg") || lowerUrl.contains(".png") || lowerUrl.contains(".gif")) return "image";
        return "doc";
    }

    /**
     * 根据基地名称获取活动图标
     */
    private String getActivityIcon(String baseName) {
        if (baseName == null) return "Flag";

        switch (baseName) {
            case "sports_meet": return "Trophy";
            case "reading_share": return "Notebook";
            case "tech_innovation": return "CPU";
            case "art_festival": return "MagicHat";
            default: return "Flag";
        }
    }

    /**
     * 获取通知类型名称
     */
    private String getNoticeTypeName(Integer typeId) {
        if (typeId == null) return "通知";

        try {
            Optional<NoticeTypeEntity> noticeType = noticeTypeRepository.findById(Long.valueOf(typeId));
            return noticeType.map(NoticeTypeEntity::getTypeName).orElse("通知");
        } catch (Exception e) {
            log.warn("获取通知类型失败: typeId={}", typeId);
            return "通知";
        }
    }

    /**
     * 获取发布人姓名
     */
    private String getSenderName(Long createdBy) {
        if (createdBy == null) return "系统管理员";

        try {
            Optional<UserEntity> sender = userRepository.findById(createdBy);
            return sender.map(user -> {
                String senderName = user.getUsername();
                if (senderName == null || senderName.trim().isEmpty()) {
                    senderName = user.getName();
                }
                return senderName != null && !senderName.trim().isEmpty() ? senderName : "系统管理员";
            }).orElse("系统管理员");
        } catch (Exception e) {
            log.warn("获取发布人信息失败: createdBy={}", createdBy);
            return "系统管理员";
        }
    }

    /**
     * 格式化日期时间
     */
    private String formatDateTime(java.time.temporal.TemporalAccessor dateTime) {
        if (dateTime == null) return "";
        try {
            return DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm").format(dateTime);
        } catch (Exception e) {
            log.warn("日期时间格式化失败: dateTime={}", dateTime);
            return "";
        }
    }
}
